#include "StdAfx.h"
#include <string>
#include <dshow.h>
#include <MacroData.h>
#include "DriverFind.h"


CDriverFind::CDriverFind(void)
{
}


CDriverFind::~CDriverFind(void)
{
}

//void CDriverFind::AddFilterToListWithMoniker(const TCHAR *szFilterName, 
//                                IMoniker *pMoniker, std::wstring& driver)
//{
//    if (!szFilterName)
//        return;
//
//    // Add the category name and a pointer to its CLSID to the list box
//    int nSuccess  = ListFilters.AddString(szFilterName);
//    int nIndexNew = ListFilters.FindStringExact(-1, szFilterName);
//
//    nSuccess = ListFilters.SetItemDataPtr(nIndexNew, pMoniker);
//}

HRESULT CDriverFind::EnumFiltersAndMonikersToList(IEnumMoniker *pEnumCat, std::wstring& driver)
{
    HRESULT hr=S_OK;
    IMoniker *pMoniker=0;
    ULONG cFetched=0;
    VARIANT varName={0};
    int nFilters=0;

    // If there are no filters of a requested type, show default string
    if (!pEnumCat)
    {
        return S_FALSE;
    }

    // Enumerate all items associated with the moniker
    while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
    {
        IPropertyBag *pPropBag;
        ASSERT(pMoniker);

        // Associate moniker with a file
        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
                                    (void **)&pPropBag);
        ASSERT(SUCCEEDED(hr));
        ASSERT(pPropBag);
        if (FAILED(hr))
            continue;

        // Read filter name from property bag
        varName.vt = VT_BSTR;
        hr = pPropBag->Read(L"FriendlyName", &varName, 0);
        if (FAILED(hr))
            continue;

        // Get filter name (converting BSTR name to a CString)
        CString str(varName.bstrVal);
        SysFreeString(varName.bstrVal);
        nFilters++;

        // Add the filter name and moniker to the listbox
        driver += str + _T(",");
       
        // Cleanup interfaces
        SAFE_RELEASE(pPropBag);

        // Intentionally DO NOT release the pMoniker, since it is
        // stored in a listbox for later use
    }

    return hr;
}
// FindCaptureDriver
HRESULT CDriverFind::FindDriver(const GUID *clsid,  std::wstring& driver)
{
	ICreateDevEnum *pSysDevEnum = NULL;
    HRESULT hr;
    IEnumMoniker *pEnumCat = NULL;

    // Instantiate the system device enumerator if it doesn't exist
    if (pSysDevEnum == NULL)
    {
        hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, 
                              CLSCTX_INPROC, IID_ICreateDevEnum, 
                              (void **)&pSysDevEnum);
        if FAILED(hr)
            return hr;
    }
	driver = L"";
    // Enumerate all filters of the selected category  
    hr = pSysDevEnum->CreateClassEnumerator(*clsid, &pEnumCat, 0);
    if (SUCCEEDED(hr))
    {
        // Enumerate all filters using the category enumerator
        hr = EnumFiltersAndMonikersToList(pEnumCat, driver);

        SAFE_RELEASE(pEnumCat);
    }

    pSysDevEnum->Release();
    return hr;
}

HRESULT CDriverFind::FindCaptureDriver( std::wstring& driver)
{
    return FindDriver(&CLSID_VideoInputDeviceCategory,driver);
}


HRESULT CDriverFind::FindAudioDriver( std::wstring& driver)
{
    return FindDriver(&CLSID_AudioInputDeviceCategory,driver);
}
